/*
 * 环形队列类
 *
 * 使用信号量支持线程安全的环形队列，对外提供push和pop接口
 *
 **/

#pragma once

#include <vector>
#include <mutex>
#include "util.hh"
#include "config.hh"
#include "task.hh"

namespace cloud
{
template<class value>
class loop_queue
{
public:
    loop_queue(size_t size = config::instance().queue_size())
        : _q(size)
        , _p_sem(size), _c_sem(0)
        , _p_step(0), _c_step(0)
    {}

public:
    void push(value v)
    {
        _p_sem.wait();
        {
            std::unique_lock<std::mutex> lock(_p_mtx);
            _q[_p_step++] = v;
            _p_step %= _q.size();
            _c_sem.post();
        }
    }

    void pop(value& v)
    {
        _c_sem.wait();
        {
            std::unique_lock<std::mutex> lock(_c_mtx);
            v = _q[_c_step++];
            _c_step %= _q.size();
            _p_sem.post();
        }
    }

private:
    std::vector<value> _q;
    std::mutex _p_mtx;
    std::mutex _c_mtx;
    util::semaphore _p_sem;
    util::semaphore _c_sem;
    int _p_step;
    int _c_step;
};
}
